/*
 * Test.cpp
 *
 *  Created on: 2009/12/29
 *      Author: kevin
 */
#include <iostream>
#include <fstream>
#include "Test.h"
#include "xDerive.h"

#ifndef WIN32
#include <sys/time.h>
#else

#endif

using namespace std;

#define ALLOCATE_TIMES 73426

void ThTarget::Run(){
	std::cout << "!sub thread ---begin!" << std::endl;

	CXDerive* pDeriveInstance[ALLOCATE_TIMES];
	for(int i = 0; i < ALLOCATE_TIMES; i++) {
		pDeriveInstance[i] = new CXDerive(i, i+1);
		//cout << pDeriveInstance[i]->GetPosX() << endl;
	}

	for(int i = 0; i < ALLOCATE_TIMES; i++) {
		delete pDeriveInstance[i];
	}

	std::cout << "!sub thread ---end!" << std::endl;

	return;
}

NormalDerive::NormalDerive()
: m_posX(0.0)
, m_posY(0.0)
{

}

NormalDerive::NormalDerive(float posX, float posY)
: m_posX(posX)
, m_posY(posY)
{

}


CTest::CTest()
: m_subThNum(1)
{

}

CTest::~CTest()
{

}

CTest::CTest(int _subThNum)
: m_subThNum(_subThNum)
{

}

THREAD_ENTRY_FUNC(CTest::test_func_entry)
{
	std::cout << "!sub thread ---begin!" << std::endl;

	NormalDerive* pDeriveInstance[ALLOCATE_TIMES];
	for(int i = 0; i < ALLOCATE_TIMES; i++) {
		pDeriveInstance[i] = new NormalDerive(i, i+1);
		//cout << pDeriveInstance[i]->GetPosX() << endl;
	}

	for(int i = 0; i < ALLOCATE_TIMES; i++){
		delete pDeriveInstance[i];
	}

	std::cout << "!sub thread ---end!" << std::endl;

	return NULL;
}

void CTest::dumpTestResult(float elapsedTime,bool bPoolUsed)
{
	cout << "The time elapsed is " << elapsedTime << "ms" << endl;

	ofstream fobj;
	if(bPoolUsed){
		fobj.open("./TestData/MemPoolResult.txt", ios_base::app);
	}else{
		fobj.open("./TestData/NormalResult.txt", ios_base::app);
	}

	fobj << "Elapsed time: " << elapsedTime;
	fobj << " Thread number: " << m_subThNum;
	fobj << " allocation times: "<< ALLOCATE_TIMES;
	fobj << '\n';

	fobj.close();
}


CMemPool::CMemPool()
{

}

CMemPool::CMemPool(int _subThNum)
: CTest(_subThNum)
{

}

void CMemPool::run_test()
{
	ThTarget target[m_subThNum];
	CXThread* p_subthreads = new CXThread[m_subThNum];

	float timeuse = 0.0;
#ifndef WIN32
	struct timeval tpstart, tpend;
	gettimeofday(&tpstart, NULL);
#else

#endif

	for(int i = 0; i < m_subThNum; i++){
		p_subthreads[i].SetRunnableTarget(&target[i]);
		p_subthreads[i].Start(); // create a new pthread and execute user specified code target->Run()
	}

	for(int i = 0; i < m_subThNum; i++){
		p_subthreads[i].Join();
	}

#ifndef WIN32
	gettimeofday(&tpend, NULL);
	timeuse = 1000 * (tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_usec - tpstart.tv_usec) / 1000;
#else

#endif

	dumpTestResult(timeuse,true);
	delete[] p_subthreads;
}


CNormal::CNormal()
{

}

CNormal::CNormal(int _subThNum)
: CTest(_subThNum)
{

}

void CNormal::run_test()
{
	thread_primative* pthreads = new thread_primative[m_subThNum];

	float timeuse = 0.0;
#ifndef WIN32
	struct timeval tpstart, tpend;
	gettimeofday(&tpstart, NULL);
#else

#endif

	for(int i = 0; i < m_subThNum; i++){

#ifndef WIN32
		int ret = -1;
		ret = pthread_create(&pthreads[i], NULL, SUPER::test_func_entry, this);
		if(ret){
			cout << "create thread failed!" << endl;
			return;
		}
#else
		unsigned tid;
		pthreads[i] = (HANDLE) _beginthreadex(NULL,0,SUPER::test_func_entry,this,0,&tid);
		if(pthreads[i] == NULL){
			cout << "create thread failed!" << endl;
			return;
		}
#endif
	}

	for(int i = 0; i < m_subThNum; i++){
#ifndef WIN32
		pthread_join(pthreads[i], NULL);
#else
		DWORD ret = WaitForSingleObject(pthreads[i], INFINITE);
		if(ret == 0xFFFFFFFF){
			cout << "thread join failed!" << endl;
		}
#endif
	}

#ifndef WIN32
	gettimeofday(&tpend, NULL);
	timeuse = 1000 * (tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_usec - tpstart.tv_usec) / 1000;
#else

#endif
	dumpTestResult(timeuse,false);
	delete[] pthreads;
}
